#include "delay.h"

// 定义CPU时钟频率，用于将时间转换为周期数  
#define CPU_CLOCK_FREQ 72000000UL    
  
// 定义与数据观察与跟踪（DWT）模块相关的寄存器地址和位掩码  
#define DEM_CR             *((volatile uint32_t *)0xE000EDFC) 
#define DWT_CR             *((volatile uint32_t *)0xE0001000) 
#define DWT_CYCCNT         *((volatile uint32_t *)0xE0001004) 
#define DEM_CR_TRCENA      0x01000000   
#define DWT_CR_CYCCNTENA   0x00000001 


// 初始化DWT（数据观察与跟踪）模块的函数  
void DWT_delay_init(void)  
{  
    DEM_CR |= DEM_CR_TRCENA;  		// 启用数据观察与跟踪模块的控制寄存器中的跟踪使能位  
    DWT_CYCCNT = 0;           		// 将周期计数器清零  
    DWT_CR |= DWT_CR_CYCCNTENA; 	// 启用周期计数器  
}  
  
// 延迟指定微秒数的函数  
void delay_us(uint32_t time)  
{  
    uint32_t cycles = (time * (CPU_CLOCK_FREQ / 1000000UL)); 	// 根据CPU时钟频率将微秒转换为周期数  
    uint32_t start_count = DWT->CYCCNT;  						// 读取周期计数器的起始值  
    uint32_t target_count = start_count + cycles; 				// 计算目标周期数（起始值加上需要延迟的周期数）  
    while(DWT_CYCCNT < target_count); 							// 等待直到周期计数器的值达到目标值  
}  
  
// 延迟指定毫秒数的函数  
void delay_ms(uint32_t time)  
{  
    time *= 1000; 				// 将毫秒转换为微秒  
    delay_us(time); 			// 调用delay_us函数来实现毫秒级的延迟  
}  

// 延迟指定秒数的函数  
void delay_s(uint32_t time)  
{  
    time *= 1000; 				// 将秒转换为豪秒  
    delay_ms(time); 			// 调用delay_ms函数来实现秒级的延迟  
} 
